"use strict";

require("core-js/modules/es.array.from");

require("core-js/modules/es.array.iterator");

require("core-js/modules/es.array.join");

require("core-js/modules/es.array.map");

require("core-js/modules/es.array.reduce");

require("core-js/modules/es.object.keys");

require("core-js/modules/es.object.to-string");

require("core-js/modules/es.promise");

require("core-js/modules/es.string.iterator");

require("core-js/modules/web.dom-collections.iterator");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.readBits = exports.readArray = exports.readUnsigned = exports.readString = exports.peekBytes = exports.readBytes = exports.peekByte = exports.readByte = exports.buildStream = void 0;

// Default stream and parsers for Uint8TypedArray data type
var buildStream = function buildStream(uint8Data) {
  return {
    data: uint8Data,
    pos: 0
  };
};

exports.buildStream = buildStream;

var readByte = function readByte() {
  return function (stream) {
    return Promise.resolve(stream.data[stream.pos++]);
  };
};

exports.readByte = readByte;

var peekByte = function peekByte() {
  var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
  return function (stream) {
    return Promise.resolve(stream.data[stream.pos + offset]);
  };
};

exports.peekByte = peekByte;

var readBytes = function readBytes(length) {
  return function (stream) {
    return Promise.resolve(stream.data.subarray(stream.pos, stream.pos += length));
  };
};

exports.readBytes = readBytes;

var peekBytes = function peekBytes(length) {
  return function (stream) {
    return Promise.resolve(stream.data.subarray(stream.pos, stream.pos + length));
  };
};

exports.peekBytes = peekBytes;

var readString = function readString(length) {
  return function (stream) {
    return readBytes(length)(stream).then(function (bytes) {
      return Array.from(bytes).map(function (value) {
        return String.fromCharCode(value);
      }).join('');
    });
  };
};

exports.readString = readString;

var readUnsigned = function readUnsigned(littleEndian) {
  return function (stream) {
    return readBytes(2)(stream).then(function (bytes) {
      return littleEndian ? (bytes[1] << 8) + bytes[0] : (bytes[0] << 8) + bytes[1];
    });
  };
};

exports.readUnsigned = readUnsigned;

var readArray = function readArray(byteSize, totalOrFunc) {
  return function (stream, result, parent) {
    var totalPromise = typeof totalOrFunc === 'function' ? totalOrFunc(stream, result, parent) : totalOrFunc;
    return Promise.resolve(totalPromise).then(function (total) {
      var parser = readBytes(byteSize);
      var arr = new Array(total);
      var promiseLoop = Promise.resolve();

      for (var i = 0; i < total; i++) {
        promiseLoop = promiseLoop.then(function (e) {
          return parser(stream);
        });
        arr[i] = promiseLoop;
      }

      return promiseLoop.then(function (e) {
        return Promise.all(arr);
      });
    });
  };
};

exports.readArray = readArray;

var subBitsTotal = function subBitsTotal(bits, startIndex, length) {
  var result = 0;

  for (var i = 0; i < length; i++) {
    result += bits[startIndex + i] && Math.pow(2, length - i - 1);
  }

  return result;
}; // export const readBits = schema => stream => {
//   const byte = readByte()(stream)
//   // convert the byte to bit array
//   const bits = new Array(8)
//   for (var i = 0; i < 8; i++) {
//     bits[7 - i] = !!(byte & (1 << i))
//   }
//   // convert the bit array to values based on the schema
//   return Object.keys(schema).reduce((res, key) => {
//     const def = schema[key]
//     if (def.length) {
//       res[key] = subBitsTotal(bits, def.index, def.length)
//     } else {
//       res[key] = bits[def.index]
//     }
//     return res
//   }, {})
// }


var readBits = function readBits(schema) {
  return function (stream) {
    return readByte()(stream).then(function (byte) {
      // convert the byte to bit array
      var bits = new Array(8);

      for (var i = 0; i < 8; i++) {
        bits[7 - i] = !!(byte & 1 << i);
      } // convert the bit array to values based on the schema


      return Object.keys(schema).reduce(function (res, key) {
        var def = schema[key];

        if (def.length) {
          res[key] = subBitsTotal(bits, def.index, def.length);
        } else {
          res[key] = bits[def.index];
        }

        return res;
      }, {});
    });
  };
};

exports.readBits = readBits;